package Schedule::Cron::Finance::Money;

use warnings;
use strict;


use base 'Class::Accessor::Complex';


use overload
    '""'  => 'stringify',
    '0+'  => 'as_number',
    '+'   => 'add',
    '-'   => 'subtract',
    '*'   => 'multiply',
    '/'   => 'divide',
    '<=>' => 'num_cmp';


__PACKAGE__->mk_new;


# getter and setter separately so subclasses can override (needed for
# Schedule::Cron::Finance::Money::Inflated)

sub _get_amount { $_[0]->{amount}         }
sub _set_amount { $_[0]->{amount} = $_[1] }

sub amount {
    my $self = shift;
    return $self->_get_amount unless @_;
    $self->_set_amount(shift);
}

sub stringify { $_[0]->amount }
sub as_number { $_[0]->amount }


my %ops = (
    add      => '+',
    subtract => '-',
    multiply => '*',
    divide   => '/',
);

while (my ($sub, $op) = each %ops) {
    no strict 'refs';
    *{$sub} = sub {
        my ($self, $other, $reversed) = @_;
        my $self_amount = $self->amount;
        my $other_amount =
            UNIVERSAL::isa($other, 'Schedule::Cron::Finance::Money')
                ? $other->amount
                : $other;
        ($self_amount, $other_amount) = ($other_amount, $self_amount)
            if $reversed;

        # make a new object, don't reuse the old one
        my $package = ref $self;
        my $result = $package->new(amount =>
            eval "\$self_amount $op \$other_amount");
        die $@ if $@;
        $result;
    }
}


sub num_cmp {
    my ($self, $other, $reversed) = @_;
    my $self_amount = $self->amount;
    my $other_amount =
        UNIVERSAL::isa($other, 'Schedule::Cron::Finance::Money')
            ? $other->amount
            : $other;
    ($self_amount, $other_amount) = ($other_amount, $self_amount)
        if $reversed;
    $self_amount <=> $other_amount;
}


1;


__END__

{% USE p = PodGenerated %}

=head1 NAME

{% p.package %} - Class representing money

=head1 SYNOPSIS

    {% p.package %}->new;

=head1 DESCRIPTION

None yet.

=head1 METHODS

=over 4

{% p.write_methods %}

=back

{% p.write_inheritance %}

{% PROCESS standard_pod %}

=cut

